home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
gnu
/
oleo-1_4.lha
/
oleo-1.4
/
key.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-30
|
10KB
|
474 lines
/* Copyright (C) 1993 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this software; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <ctype.h>
#include "key.h"
#include "cmd.h"
#include "io-abstract.h"
#include "io-generic.h"
#include "io-utils.h"
#include "io-term.h"
struct keymap **the_maps;
char **map_names;
char **map_prompts;
int num_maps;
struct cmd_func **the_funcs;
int num_funcs;
#ifdef __STDC__
int
search_map_for_cmd (struct line * line, int map, int vec, int code)
#else
int
search_map_for_cmd (line, map, vec, code)
struct line * line;
int map;
int vec;
int code;
#endif
{
int len = strlen (line->buf);
struct keymap * this_map;
int x;
char used[256];
int try_prefix;
for (try_prefix = 0; try_prefix < 2; ++try_prefix)
{
bzero (used, sizeof (used));
for (this_map = the_maps[map]; this_map; this_map = this_map->map_next)
{
for (x = 128; x >= 0; --x)
if (!used[x])
{
int found_it = ((this_map->keys[x].vector == vec)
&& this_map->keys[x].code == code);
int prefix_key = ((this_map->keys[x].vector == -1)
&& (this_map->keys[x].code != -1));
if (!( (this_map->keys[x].vector == -1)
&& (this_map->keys[x].code == -1)))
used[x] = 1;
if (found_it || (try_prefix && prefix_key))
{
char * c = char_to_string (x);
catn_line (line, " ", 1);
catn_line (line, c, strlen (c));
if (found_it
|| (try_prefix
&& search_map_for_cmd (line,
this_map->keys[x].code,
vec, code)))
return 1;
line->buf[len] = 0;
}
}
}
}
return 0;
}
#ifdef __STDC__
static void
do_bind_key (struct keymap *m, int key, int vector, int code)
#else
static void
do_bind_key (m, key, vector, code)
struct keymap *m;
int key;
int vector;
int code;
#endif
{
m->keys[key].vector = (short)vector;
m->keys[key].code = (short)code;
}
#ifdef __STDC__
void
bind_key (char * keymap, char * function, int ch)
#else
void
bind_key (keymap, function, ch)
char * keymap;
char * function;
int ch;
#endif
{
struct cmd_func * tmpfunc;
int map = map_id (keymap);
int vec;
int code;
struct rng rng;
struct cmd_func * cmd;
if (map < 0)
{
io_error_msg ("bind_key: bad keymap.");
return;
}
if (!find_func (&vec, &cmd, function))
{
code = (cmd - the_funcs[vec]);
goto fini;
}
for (code = 0; code < num_maps; code++)
{
if (!strcmp (function, map_names[code]))
{
vec = -1;
goto fini;
}
}
if (get_abs_rng (&function, &rng))
{
io_error_msg ("Unknown command '%s'", function);
return;
}
for (code = 0; code < n_bound_macros; code++)
{
if (!bcmp (&bound_macros[code], &rng, sizeof (struct rng)))
goto fini;
}
function = range_name (&rng);
if (!bound_macro_vec)
{
bound_macros = ck_malloc (sizeof (struct rng));
n_bound_macros = 1;
tmpfunc = (struct cmd_func *)ck_malloc (2 * sizeof (struct cmd_func));
bzero (tmpfunc + 1, sizeof (*tmpfunc));
bound_macro_vec = add_usr_cmds (tmpfunc);
}
else
{
n_bound_macros++;
bound_macros = ck_realloc (bound_macros,
n_bound_macros * sizeof (struct rng));
the_funcs[bound_macro_vec]
= ck_realloc (the_funcs[bound_macro_vec],
(1 + n_bound_macros) * sizeof (struct cmd_func));
tmpfunc = &the_funcs[bound_macro_vec][n_bound_macros - 1];
bzero (tmpfunc + 1, sizeof (*tmpfunc));
}
vec = bound_macro_vec;
bound_macros[n_bound_macros - 1] = rng;
tmpfunc->func_args = (char **)ck_malloc (2 * sizeof (char *));
tmpfunc->func_args[0] = mk_sprintf ("#%d", n_bound_macros - 1);
tmpfunc->func_args[1] = 0;
tmpfunc->init_code = 0;
tmpfunc->func_doc = 0;
tmpfunc->func_name = ck_savestr (function);
tmpfunc->func_func = bound_macro;
fini:
do_bind_key (the_maps[map], ch, vec, code);
}
#ifdef __STDC__
void
bind_set (char * keymap, char * command, char * keyset)
#else
void
bind_set (keymap, command, keyset)
char * keymap;
char * command;
char * keyset;
#endif
{
int first;
int last;
first = string_to_char (&keyset);
if (first < 0)
{
io_error_msg ("Invalid character set.");
return;
}
while (isspace (*keyset))
++keyset;
if (*keyset == '-')
{
++keyset;
last = string_to_char (&keyset);
if (last < 0)
{
io_error_msg ("Unterminated character set.");
return;
}
}
else if (*keyset)
{
io_error_msg ("Extra characters in keyset: `%s'.",
keyset);
return;
}
else
last = first;
while (first <= last)
{
bind_key (keymap, command, first);
++first;
}
}
#ifdef __STDC__
void
bind_all_keys (char * keymap, char * function)
#else
void
bind_all_keys (keymap, function)
char * keymap;
char * function;
#endif
{
struct cmd_func * tmpfunc;
int map = map_id (keymap);
int vec;
int code;
struct rng rng;
struct cmd_func * cmd;
if (map < 0)
{
io_error_msg ("bind_key: bad keymap.");
return;
}
if (!find_func (&vec, &cmd, function))
{
code = (cmd - the_funcs[vec]);
goto fini;
}
for (code = 0; code < num_maps; code++)
{
if (!strcmp (function, map_names[code]))
{
vec = -1;
goto fini;
}
}
if (get_abs_rng (&function, &rng))
{
io_error_msg ("Unknown command '%s'", function);
return;
}
vec = bound_macro_vec;
for (code = 0; code < n_bound_macros; code++)
{
if (!bcmp (&bound_macros[code], &rng, sizeof (struct rng)))
goto fini;
}
function = range_name (&rng);
if (!bound_macro_vec)
{
bound_macros = ck_malloc (sizeof (struct rng));
n_bound_macros = 1;
tmpfunc = (struct cmd_func *)ck_malloc (2 * sizeof (struct cmd_func));
bzero (tmpfunc + 1, sizeof (*tmpfunc));
bound_macro_vec = add_usr_cmds (tmpfunc);
}
else
{
n_bound_macros++;
bound_macros = ck_realloc (bound_macros,
n_bound_macros * sizeof (struct rng));
the_funcs[bound_macro_vec]
= ck_realloc (the_funcs[bound_macro_vec],
(1 + n_bound_macros) * sizeof (struct cmd_func));
tmpfunc = &the_funcs[bound_macro_vec][n_bound_macros - 1];
bzero (tmpfunc + 1, sizeof (*tmpfunc));
}
bound_macros[n_bound_macros - 1] = rng;
tmpfunc->func_args = (char **)ck_malloc (2 * sizeof (char *));
tmpfunc->func_args[0] = mk_sprintf ("#%d", n_bound_macros - 1);
tmpfunc->func_args[1] = 0;
tmpfunc->func_doc = 0;
tmpfunc->func_name = ck_savestr (function);
tmpfunc->func_func = bound_macro;
fini:
{
int ch;
for (ch = 0; ch < 256; ++ch)
do_bind_key (the_maps[map], ch, vec, code);
}
}
#ifdef __STDC__
void
write_keys_cmd (FILE *fp)
#else
void
write_keys_cmd (fp)
FILE *fp;
#endif
{
struct keymap *map;
int n;
int key;
int vec;
int code;
for (n = 0; n < num_maps; n++)
{
char *def;
map = the_maps[n];
def = 0;
if (map && map->map_next)
{
for (key = 0; key < num_maps; key++)
if (the_maps[key] == map->map_next)
{
def = map_names[key];
break;
}
}
if (def)
fprintf (fp, "create-keymap %s %s\n", map_names[n], def);
else
fprintf (fp, "create-keymap %s\n", map_names[n]);
}
for (n = 0; n < num_maps; n++)
{
map = the_maps[n];
for (key = 0; key < 256; key++)
{
vec = map->keys[key].vector;
code = map->keys[key].code;
if (vec < 0 && code >= 0)
fprintf (fp, "bind-key %s %s %s\n",
map_names[n],
map_names[code],
char_to_string (key));
else if (vec >= 0)
fprintf (fp, "bind-key %s %s %s\n",
map_names[n],
the_funcs[vec][code].func_name,
char_to_string (key));
}
}
}
#ifdef __STDC__
void
clear_keymap (struct keymap *m)
#else
void
clear_keymap (m)
struct keymap *m;
#endif
{
int n;
for (n = 0; n < 256; n++)
{
m->keys[n].vector = -1;
m->keys[n].code = -1;
}
}
#ifdef __STDC__
int
map_idn (char *name, int n)
#else
int
map_idn (name, n)
char *name;
int n;
#endif
{
int x;
for (x = 0; x < num_maps; ++x)
if (!strincmp (name, map_names[x], n))
return x;
return -1;
}
#ifdef __STDC__
void
create_keymap (char * mapname, char * parentname)
#else
void
create_keymap (mapname, parentname)
char * mapname;
char * parentname;
#endif
{
int map = map_id (mapname);
int parent = parentname ? map_id (parentname) : -1;
if (map > 0)
{
io_info_msg ("Map %s already exists.", mapname);
return;
}
if (parentname && (parent < 0))
{
io_error_msg ("Map %s does not exist.", parentname);
return;
}
the_maps = ck_realloc (the_maps, (num_maps + 1) * sizeof (struct keymap *));
the_maps[num_maps] = ck_malloc (sizeof (struct keymap));
the_maps[num_maps]->id = num_maps;
the_maps[num_maps]->map_next = ((parent >= 0)
? the_maps[parent]
: 0);
{
int c;
for (c = 0; c < 256; ++c)
{
the_maps[num_maps]->keys[c].vector = -1;
the_maps[num_maps]->keys[c].code = -1;
}
}
map_names = ck_realloc (map_names, (num_maps + 1) * sizeof (char *));
map_prompts = ck_realloc (map_prompts, (num_maps + 1) * sizeof (char *));
map_names[num_maps] = ck_savestr (mapname);
map_prompts[num_maps] = 0;
num_maps++;
}
#ifdef __STDC__
void
set_map_prompt (char * map, char * str)
#else
void
set_map_prompt (map, str)
char * map;
char * str;
#endif
{
int id = map_id (map);
if (id < 0)
io_error_msg ("No such keymap as %s.", map); /* No return. */
if (map_prompts[id])
free (map_prompts [id]);
map_prompts[id] = ck_savestr (str);
}